#include <assert.h>
#include <Windows.h>
#include "TableHandler.h"
#include "sqlite3.h"

TableHandler::TableHandler(void)
{
	m_pSqlite = NULL;
}

TableHandler::~TableHandler(void)
{
}

int TableHandler::Initialize(sqlite3* pSqlite, const char* pTableName)
{
	assert(m_pSqlite == NULL && pSqlite != NULL && pTableName != NULL);

	m_pSqlite = pSqlite;
	m_TableName = pTableName;
	return CreateTable();
}

char* WChar2Ansi(LPCWSTR pwszSrc)
{
	assert(pwszSrc != NULL);

	int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);
	char* pszDst = new char[nLen + 1];
	WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen + 1, NULL, NULL);
	pszDst[nLen] = '\0';
	return pszDst;
}

wchar_t* AnsiToUnicode(const char* szStr)
{
	int nLen = MultiByteToWideChar(CP_ACP, 0, szStr, -1, NULL, 0);
	if (nLen == 0)
	{
	   return NULL;
	}
	wchar_t* pResult = new wchar_t[nLen];
	MultiByteToWideChar(CP_ACP, 0, szStr, -1, pResult, nLen);
	return pResult;
}

int TableHandler::Translate(const char* pText, char** pResult) const
{
	assert(m_pSqlite != NULL && pText != NULL && pResult != NULL);

	std::string sql = "SELECT Translated FROM ";
	sql.append(m_TableName);
	sql.append(" WHERE NAME=\'");
	sql.append(pText);
	sql.append("\'");

	sqlite3_stmt* sqlStmt;
	int result = sqlite3_prepare_v2(m_pSqlite, sql.c_str(), static_cast<int>(sql.size()), &sqlStmt, NULL);
	result = (result == SQLITE_OK) ? sqlite3_step(sqlStmt) : result;
	if (result == SQLITE_ROW)
	{
		const void* pTranslatedText = sqlite3_column_text16(sqlStmt, 0);
		*pResult = WChar2Ansi((LPCWSTR)pTranslatedText);
		result = SQLITE_OK;
	}
	sqlite3_finalize(sqlStmt);
	sqlStmt = NULL;

	return result;
}

int TableHandler::AppendOriginalText(int nFormID, const char* pOriginalName)
{
	assert(m_pSqlite != NULL && pOriginalName != NULL);

	std::string sql = "INSERT INTO ";
	sql.append(m_TableName);
	sql.append(" (FormID,Name) VALUES(?,?);");

	sqlite3_stmt* sqlStmt;
	int result = sqlite3_prepare_v2(m_pSqlite, sql.c_str(), static_cast<int>(sql.size()), &sqlStmt, NULL);
	result = (result == SQLITE_OK) ? sqlite3_bind_int(sqlStmt, 1, nFormID) : result;
	result = (result == SQLITE_OK) ? sqlite3_bind_text(sqlStmt, 2, pOriginalName, -1, SQLITE_STATIC) : result;
	result = (result == SQLITE_OK) ? sqlite3_step(sqlStmt) : result;
	sqlite3_finalize(sqlStmt);
	sqlStmt = NULL;

	return result;
}

int TableHandler::AppendTranslatedText(int nFormID, const char* pTranslatedName)
{
	assert(m_pSqlite != NULL && nFormID != 0 && pTranslatedName != NULL);

	std::string sql = "UPDATE ";
	sql.append(m_TableName);
	sql.append(" SET Translated = ?1 WHERE FormId = ?2");

	wchar_t* p = AnsiToUnicode(pTranslatedName);

	sqlite3_stmt* sqlStmt;
	int result = sqlite3_prepare_v2(m_pSqlite, sql.c_str(), static_cast<int>(sql.size()), &sqlStmt, NULL);
	result = (result == SQLITE_OK) ? sqlite3_bind_text16(sqlStmt, 1, p, -1, SQLITE_STATIC) : result;
	result = (result == SQLITE_OK) ? sqlite3_bind_int(sqlStmt, 2, nFormID) : result;
	result = (result == SQLITE_OK) ? sqlite3_step(sqlStmt) : result;
	sqlite3_finalize(sqlStmt);
	sqlStmt = NULL;

	delete [] p;

	return result;
}

//CREATE TABLE IF NOT EXISTS "TableName" ("RecordID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, "FormID" INTEGER, "Name" TEXT NOT NULL UNIQUE, "Translated" TEXT)
int TableHandler::CreateTable(void)
{
	// Always create the table.
	std::string sql = "CREATE TABLE IF NOT EXISTS \"";
	sql.append(m_TableName);
	sql.append("\" (\"RecordID\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, \"FormId\" INTEGER NOT NULL, \"Name\" TEXT NOT NULL UNIQUE, \"Translated\" TEXT )");

	sqlite3_stmt* sqlStmt;
	int result = sqlite3_prepare_v2(m_pSqlite, sql.c_str(), static_cast<int>(sql.size()), &sqlStmt, NULL);
	result = (result == SQLITE_OK) ? sqlite3_step(sqlStmt) : result;

	if (result == SQLITE_DONE)
	{
		// Success
		result = SQLITE_OK;
	}

	sqlite3_finalize(sqlStmt);
	sqlStmt = NULL;

	return result;
}
